package jdk8.stream;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamEndOperate {

	public static void main(String[] args) {
		//1,2,3,4,5....10
		List<Integer> intList = Stream.iterate(1, x -> x+1).limit(10).collect(Collectors.toList());
		//求intList集合中所有元素之和
		int total = intList.stream().reduce(0, new BinaryOperator<Integer>() {
			//此处的参数t，第一次会被0填充[也就是reduce方法的第1个参数], 从第二次执行开始，此参数t的值就是方法apply的返回值
			//而参数u, 是被遍历的集合中的元素，每执行1次，传入一个元素，此处依次是1,2,3,4,5,...10
			public Integer apply(Integer t, Integer u) {
				System.out.printf("t:%d -> u:%d\n",t, u);
				//
				return t+u;
			};
		}).intValue();
		//
		System.out.println(total);
		//理解了上面的代码后，再来连写： [以下代码表示求 1~10之和]
		total = Stream.iterate(1, x -> x + 1).limit(10)
							.reduce(0,  (t,u) -> t+u).intValue();
		System.out.printf("total: %d\n",total);
		
		System.out.println("----------------------------------");
		//
		intList.stream().reduce(new BinaryOperator<Integer>() {
			//先从流中取出2个元素，分别赋值给t 和u,后面的操作与 reduce(T seed, BinaryOperator)是一样的。
			@Override
			public Integer apply(Integer t, Integer u) {
				System.out.printf("t:%d -> u:%d\n",t, u);
				return t+u;
			}
		});
		
		//
		List<Order> ordList = getOrderList();
		//把这个List<Order>转换成 Map<String, Order>
		/*****
		 * <R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);
		 */
		//1.方式一，使用 collect 三参方法
		/*
		Map<String, Order> map = ordList.stream().collect(
							new Supplier<Map<String, Order>>() {
							@Override
							public Map<String, Order> get() {
								return new HashMap<String, Order>();
							}
						}, new BiConsumer<Map<String, Order>, Order>() {
							@Override
							public void accept(Map<String, Order> t, Order u) {
								t.put(u.getOrdNo(), u);
							}
						}, new BiConsumer<Map<String, Order>, Map<String, Order>>() {
							public void accept(Map<String,Order> t, Map<String, Order> u) {
								t.putAll(u);
							};
						});
		//
		map.forEach((key,value) -> System.out.printf("key: %s \n\t%s\n", key, value));
		*/
		//连写：
		Map<String, Order> map = ordList.stream().
					collect(HashMap::new, (t, u) -> t.put(u.getOrdNo(),u), (m,p) -> m.putAll(p));
		map.forEach((key,value) -> System.out.printf("key: %s \n\t%s\n", key, value));
		
		System.out.println("=======================================================");
		//方式二，使用 Collectors工具类：
		/****
		 * <R, A> R collect(Collector<? super T, A, R> collector);
		 */
		map = ordList.stream().collect(Collectors.toMap(Order::getOrdNo, (o) -> o));
		map.forEach((key,value) -> System.out.printf("key: %s \n\t%s\n", key, value));
		
	}
	
	private static List<Order> getOrderList() {
		Order o1 = new Order("1001", 45.6, OrderStatus.已付款, LocalDateTime.of(2020, 8, 13, 12, 15,38));
		Order o2 = new Order("1002", 145.6, OrderStatus.已付款, LocalDateTime.of(2020, 8, 18, 12, 15,38));
		Order o3 = new Order("1003", 445.6, OrderStatus.已付款, LocalDateTime.of(2020, 8, 30, 12, 15,38));
		Order o4 = new Order("1004", 15.6, OrderStatus.已发货, LocalDateTime.of(2020, 8, 29, 12, 15,38));
		Order o5 = new Order("1005", 67.6, OrderStatus.已发货, LocalDateTime.of(2020, 8, 27, 12, 15,38));
		Order o6 = new Order("1006", 119.6, OrderStatus.已取消, LocalDateTime.of(2020, 8, 20, 12, 15,38));
		Order o7 = new Order("1007", 28.6, OrderStatus.已签收, LocalDateTime.of(2020, 8, 18, 12, 15,38));
		Order o8 = new Order("1008", 345.6, OrderStatus.已签收, LocalDateTime.of(2020, 8, 12, 12, 15,38));
		Order o9 = new Order("1009", 1405.6, OrderStatus.未发货, LocalDateTime.of(2020, 9, 2, 18, 15,38));
		Order o10 = new Order("1010", 245.6, OrderStatus.未发货, LocalDateTime.of(2020, 9, 2, 17, 15,38));
		return Arrays.asList(o1,o2,o3,o4,o5,o6,o7,o8,o9,o10);
	}
}


